<script setup>
import { ref, reactive, watch } from 'vue'

// 定义props
const props = defineProps({
  // 表单数据
  modelValue: {
    type: Object,
    required: true
  },
  // 表单字段配置
  fields: {
    type: Array,
    required: true
  },
  // 表单规则
  rules: {
    type: Object,
    default: () => ({})
  },
  // 表单标签宽度
  labelWidth: {
    type: String,
    default: '100px'
  },
  // 表单尺寸
  size: {
    type: String,
    default: 'default'
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否只读
  readonly: {
    type: Boolean,
    default: false
  }
})

// 定义事件
const emit = defineEmits(['update:modelValue', 'submit', 'cancel'])

// 表单引用
const formRef = ref(null)

// 表单数据
const formData = reactive({})

// 初始化表单数据
const initFormData = () => {
  Object.keys(props.modelValue).forEach(key => {
    formData[key] = props.modelValue[key]
  })
}

// 监听modelValue变化
watch(
  () => props.modelValue,
  () => {
    initFormData()
  },
  { deep: true, immediate: true }
)

// 监听formData变化
watch(
  () => formData,
  (newVal) => {
    emit('update:modelValue', { ...newVal })
  },
  { deep: true }
)

// 表单验证
const validate = async () => {
  if (formRef.value) {
    return await formRef.value.validate()
  }
  return Promise.resolve(true)
}

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }
}

// 提交表单
const submitForm = async () => {
  try {
    await validate()
    emit('submit', { ...formData })
  } catch (error) {
    console.error('表单验证失败', error)
  }
}

// 取消
const cancelForm = () => {
  resetForm()
  emit('cancel')
}

// 暴露方法
defineExpose({
  validate,
  resetForm,
  submitForm
})
</script>

<template>
  <el-form
    ref="formRef"
    :model="formData"
    :rules="rules"
    :label-width="labelWidth"
    :size="size"
    :disabled="disabled"
  >
    <el-row :gutter="20">
      <el-col
        v-for="(field, index) in fields"
        :key="index"
        :span="field.span || 24"
        :offset="field.offset || 0"
      >
        <el-form-item
          :label="field.label"
          :prop="field.prop"
          :required="field.required"
        >
          <!-- 输入框 -->
          <el-input
            v-if="field.type === 'input'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder || `请输入${field.label}`"
            :readonly="readonly || field.readonly"
            :disabled="field.disabled"
            :clearable="field.clearable !== false"
            :prefix-icon="field.prefixIcon"
            :suffix-icon="field.suffixIcon"
            :type="field.inputType || 'text'"
            :maxlength="field.maxlength"
            :show-word-limit="field.showWordLimit"
          />

          <!-- 文本域 -->
          <el-input
            v-else-if="field.type === 'textarea'"
            v-model="formData[field.prop]"
            type="textarea"
            :placeholder="field.placeholder || `请输入${field.label}`"
            :readonly="readonly || field.readonly"
            :disabled="field.disabled"
            :rows="field.rows || 3"
            :maxlength="field.maxlength"
            :show-word-limit="field.showWordLimit"
          />

          <!-- 数字输入框 -->
          <el-input-number
            v-else-if="field.type === 'number'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder || `请输入${field.label}`"
            :readonly="readonly || field.readonly"
            :disabled="field.disabled"
            :min="field.min"
            :max="field.max"
            :step="field.step || 1"
            :precision="field.precision"
            :controls="field.controls !== false"
            :controls-position="field.controlsPosition"
          />

          <!-- 选择器 -->
          <el-select
            v-else-if="field.type === 'select'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder || `请选择${field.label}`"
            :disabled="readonly || field.disabled"
            :clearable="field.clearable !== false"
            :multiple="field.multiple"
            :filterable="field.filterable"
            :remote="field.remote"
            :loading="field.loading"
            :remote-method="field.remoteMethod"
          >
            <el-option
              v-for="(option, optionIndex) in field.options"
              :key="optionIndex"
              :label="option.label"
              :value="option.value"
              :disabled="option.disabled"
            />
          </el-select>

          <!-- 单选框组 -->
          <el-radio-group
            v-else-if="field.type === 'radio'"
            v-model="formData[field.prop]"
            :disabled="readonly || field.disabled"
          >
            <el-radio
              v-for="(option, optionIndex) in field.options"
              :key="optionIndex"
              :label="option.value"
              :disabled="option.disabled"
            >
              {{ option.label }}
            </el-radio>
          </el-radio-group>

          <!-- 复选框组 -->
          <el-checkbox-group
            v-else-if="field.type === 'checkbox'"
            v-model="formData[field.prop]"
            :disabled="readonly || field.disabled"
          >
            <el-checkbox
              v-for="(option, optionIndex) in field.options"
              :key="optionIndex"
              :label="option.value"
              :disabled="option.disabled"
            >
              {{ option.label }}
            </el-checkbox>
          </el-checkbox-group>

          <!-- 开关 -->
          <el-switch
            v-else-if="field.type === 'switch'"
            v-model="formData[field.prop]"
            :disabled="readonly || field.disabled"
            :active-text="field.activeText"
            :inactive-text="field.inactiveText"
            :active-value="field.activeValue"
            :inactive-value="field.inactiveValue"
          />

          <!-- 日期选择器 -->
          <el-date-picker
            v-else-if="field.type === 'date'"
            v-model="formData[field.prop]"
            :type="field.dateType || 'date'"
            :placeholder="field.placeholder || `请选择${field.label}`"
            :readonly="readonly || field.readonly"
            :disabled="field.disabled"
            :format="field.format"
            :value-format="field.valueFormat"
            :clearable="field.clearable !== false"
            :start-placeholder="field.startPlaceholder"
            :end-placeholder="field.endPlaceholder"
          />

          <!-- 时间选择器 -->
          <el-time-picker
            v-else-if="field.type === 'time'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder || `请选择${field.label}`"
            :readonly="readonly || field.readonly"
            :disabled="field.disabled"
            :format="field.format"
            :value-format="field.valueFormat"
            :clearable="field.clearable !== false"
          />

          <!-- 自定义插槽 -->
          <slot v-else :name="field.prop" :field="field" :form-data="formData"></slot>
        </el-form-item>
      </el-col>
    </el-row>

    <!-- 表单按钮 -->
    <el-form-item v-if="$slots.footer">
      <slot name="footer"></slot>
    </el-form-item>
    <el-form-item v-else>
      <el-button type="primary" @click="submitForm" :disabled="disabled">提交</el-button>
      <el-button @click="cancelForm">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<style scoped>
.el-form {
  width: 100%;
}
</style> 